import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const Text("Animation Widget Demo"),
      ),
      body: AnimatedSwitcherCounterWidget(),
    ),
  ));
}

class AnimatedSwitcherCounterWidget extends StatefulWidget {
  const AnimatedSwitcherCounterWidget({Key? key}) : super(key: key);

  @override
  _AnimatedSwitcherCounterWidgetState createState() =>
      _AnimatedSwitcherCounterWidgetState();
}

class _AnimatedSwitcherCounterWidgetState
    extends State<AnimatedSwitcherCounterWidget> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          // AnimatedSwitcher不能实现旧页面屏幕中向左侧平移退出，新页面从屏幕右侧平移进入，因为动画是对称的
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 200),
            transitionBuilder: (Widget child, Animation<double> animation) {
              var tween = Tween<Offset>(
                  begin: const Offset(1, 0), end: const Offset(0, 0));
              return CustomSlideTransition(
                position: tween.animate(animation),
                child: child,
              );
            },
            child: Text(
              '$_count',
              //显示指定key，不同的key会被认为是不同的Text，这样才能执行动画
              key: ValueKey<int>(_count),
              style: Theme.of(context).textTheme.headline4,
            ),
          ),
          ElevatedButton(
            child: const Text(
              '+1',
            ),
            onPressed: () {
              setState(() {
                _count += 1;
              });
            },
          ),
        ],
      ),
    );
  }
}

class CustomSlideTransition extends AnimatedWidget {
  final bool transformHitTests;
  final Widget child;

  const CustomSlideTransition(
      {Key? key,
      this.transformHitTests = true,
      required this.child,
      required Animation<Offset> position})
      : super(key: key, listenable: position);

  @override
  Widget build(BuildContext context) {
    final position = listenable as Animation<Offset>;
    Offset offset = position.value;
    if (position.status == AnimationStatus.reverse) {
      offset = Offset(-offset.dx, offset.dy);
    }
    return FractionalTranslation(
      translation: offset,
      transformHitTests: transformHitTests,
      child: child,
    );
  }
}
